<template>
  <div class="data-type-form-container">
    <el-form ref="form" :model="form" label-position="top" style="max-width: 450px; min-width: 420px">
      <!-- 下拉更换数据类型 -->
      <el-form-item>
        <el-select v-model="form.type" style="width: 100%" :class="[form.type ? form.type + '-text' : '']"
          @change="handleChangeDataType">
          <el-option-group v-for="group in typeOptions" :key="group.label" :label="group.label">
            <el-option v-for="item in group.options" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-option-group>
        </el-select>
      </el-form-item>
      <div class="hr-color"></div>
      <template v-if="form.type === 'integer' || form.type === 'number'">
        <el-row :gutter="10" style="width: 100%; font-size: 12px">
          <el-col :span="8">
            <el-form-item label="format">
              <el-popover ref="formatRef" width="140" popper-class="common-popover scroll-popover" placement="bottom-start" trigger="click"
                :visible-arrow="false">
                <div class="menu-item" v-for="item in form.type === 'integer'
                  ? format_options.integer_format_options
                  : format_options.number_format_options" :key="item.value" @click="handleFormatClick(item)">
                  <div class="menu-item-text">{{ item.label }}</div>
                </div>

                <el-input slot="reference" v-model="form.format" placeholder="" clearable
                  style="width: 100%"></el-input>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="最小值">
              <el-input v-model.number="form.minimum" placeholder="> = 0" style="width: 100%"
                @change="handleChange($event, 'minimum')"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="最大值">
              <el-input v-model.number="form.maximum" placeholder="> = 0" style="width: 100%"
                @change="handleChange($event, 'maximum')"></el-input>
            </el-form-item>
          </el-col>

        </el-row>
        <el-row :gutter="10" style="width: 100%; font-size: 12px">
          <el-col :span="8" style="border: 1px solid transparent; min-height: 1px"></el-col>
          <el-col :span="8">
            <el-checkbox size="mini" :checked="form.exclusiveMinimum ? true : false"
              :disabled="form.minimum ? false : true" v-model="form.exclusiveMinimum" :true-label="form.minimum"
              false-label="" @change="handleCheckBoxChange($event, 'exclusiveMinimum')">不可等于最小值
            </el-checkbox>
          </el-col>
          <el-col :span="8">
            <el-checkbox size="mini" :checked="form.exclusiveMaximum ? true : false"
              :disabled="form.maximum ? false : true" v-model="form.exclusiveMaximum" :true-label="form.maximum"
              false-label="" @change="handleCheckBoxChange($event, 'exclusiveMaximum')">不可等于最大值
            </el-checkbox>
          </el-col>
        </el-row>
      </template>
      <template v-else-if="form.type === 'quote'">
        <ReferenceDialogAdvanced ref="referenceRef" :modelDataList="treeData" :isGlobalModule="isGlobalModule"
          @addReferenceModel="addReferenceModel"></ReferenceDialogAdvanced>
      </template>
    </el-form>
  </div>
</template>

<script>
import { mapState } from "vuex";
import jsonSchemaToolHandle from "@/utils/jsonSchema-tool.js";
import ReferenceDialogAdvanced from "./reference-dialog-advanced.vue";
export default {
  name: "DataTypeForm",
  data() {
    return {
      jsonSchemaTool: null,
      currentNodeKey: null, // 当前节点的key
      filterText: null,
      isQuote: false, // 判断是否是点击数据类型，将其修改为引用类型
      format_options: {}, // format的格式列表
      treeList: [], // 引用模型列表
      form: {
        type: "quote",
        required: false,
        null_able: false,
      },
      defaultProps: {
        children: "children",
        label: "name",
        value: "id",
      },
      // ready:false,//是否加载树
      modelInfo: {}, //模型信息
      mainVersionInfo: {}, //模型主版本信息
    };
  },
  props: {
    popoverRef: {
      type: String,
    },
    formRef: {
      type: String,
    },
    parentSchema: {
      type: Object,
    },
    currentSchema: {
      type: Object,
    },
    currentName: {
      type: String,
    },
    currentIndex: {
      type: Number,
    },
    isArrayItems: {
      type: String,
    },
    treeData: {
      type: Array,
    },
    globalTreeData: {
      type: Array,
    },
    isGlobalModule: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    ReferenceDialogAdvanced,
  },
  computed: {
    ...mapState({
      list4: (state) => state.model_scenario.menu_list.list4,
      list5: (state) => state.model_scenario.menu_list.list5,
    }),
    typeOptions() {
      return this.isArrayItems == "key"
        ? [
          {
            label: "基础类型",
            options: this.list4[1].options.filter((item) =>
              ["string", "integer"].includes(item.value)
            ),
          },
        ]
        : this.list4;
    },
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
  },
  created() {
    this.jsonSchemaTool = new jsonSchemaToolHandle(this);
  },
  methods: {
    init() {
      this.currentNodeKey = null;
      this.treeList = this.$store.getters.data_model_tree_data;
      this.format_options = this.$store.getters.format_options;
      this.initForm();
      if (this.jsonSchemaTool.isComplexType(this.currentSchema, 2)) {
        // 当前节点的类型为引用
        this.currentNodeKey = `apiSchema.${this.currentSchema["$ref"]
          .split("/")
          .pop()}`;
        // this.$nextTick(() => {
        //   this.$refs["tree"].setCurrentKey(this.currentNodeKey);
        // });
      }
    },
    // 筛选树节点
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },

    // 处理选择的引用模型
    addReferenceModel(isSelectRefGlobal, data) {
      if (isSelectRefGlobal) {
        this.globalHandleNodeClick(data)
      } else {
        this.handleNodeClick(data)
      }
    },
    // 模型管理树节点点击事件
    handleNodeClick(data) {
      if (this.jsonSchemaTool.isFolder(data)) {
        this.$nextTick(() => {
          this.$refs["tree"].setCurrentKey(this.currentNodeKey);
        });
        return;
      }
      this.currentNodeKey = data.key;
      this.$emit(
        "updateSchemaWhenQuote",
        "definitions",
        this.currentName,
        data,
        this.isArrayItems
      );
    },
    // 全局数据模型树节点点击事件
    globalHandleNodeClick(data) {
      if (this.jsonSchemaTool.isFolder(data)) {
        this.$nextTick(() => {
          this.$refs["tree"].setCurrentKey(this.currentNodeKey);
        });
        return;
      }
      this.currentNodeKey = data.key;
      this.$emit(
        "updateSchemaWhenQuote",
        "globalDefinitions",
        this.currentName,
        data,
        this.isArrayItems
      );
    },
    // 根据数据类型，初始化表单数据
    initForm(val) {
      this.form = {
        type: !val ? this.returnType() : val,
        required:
          this.currentIndex == 1 &&
            this.jsonSchemaTool.isComplexType(this.currentSchema, 0)
            ? false
            : !this.parentSchema["required"]
              ? false
              : this.parentSchema["required"].includes(this.currentName),
        null_able: this.jsonSchemaTool.isNullAble(this.currentSchema),
      };
      switch (this.form.type) {
        case "integer":
        case "number":
          this.form = {
            ...this.form,
            format: this.currentSchema.format
              ? this.currentSchema.format
              : null, // format 格式
            minimum: this.currentSchema.minimum
              ? this.currentSchema.minimum
              : null, // 最小值
            maximum: this.currentSchema.maximum
              ? this.currentSchema.maximum
              : null, // 最大值
            exclusiveMinimum: this.currentSchema.exclusiveMinimum,
            exclusiveMaximum: this.currentSchema.exclusiveMaximum
          };
          this.$forceUpdate();
          break;
        case "boolean":
        case "array":
        case "object":
        case "quote":
        case "string":
        case "null":
        case "any":
        case "dictionary":
          break;
      }
      this.$emit("updatePopoverPos", this.popoverRef);
    },
    // 获取type类型
    returnType() {
      if (this.isQuote) {
        return "quote";
      } else {
        if (this.jsonSchemaTool.isComplexType(this.currentSchema, 0, 1, 2, 4)) {
          // 当前节点的类型为数组、对象、引用、组合模式之一
          if (this.jsonSchemaTool.isComplexType(this.currentSchema, 0)) {
            // 数组
            return "array";
          } else {
            return this.jsonSchemaTool.isComplexType(this.currentSchema, 2)
              ? "quote"
              : this.jsonSchemaTool.isComplexType(this.currentSchema, 4)
                ? "dictionary"
                : "object";
          }
        } else {
          // 当前节点的类型为基本类型
          return Array.isArray(this.currentSchema.type)
            ? this.currentSchema.type.length == 2
              ? this.currentSchema.type[0]
              : "any"
            : this.currentSchema.type;
        }
      }
    },
    // 当选择的数据类型发生变化后
    handleChangeDataType(val) {
      this.initForm(val);
      if (val == "quote") return;
      this.$emit(
        "updateSchemaStructure",
        val,
        this.isArrayItems,
        this.popoverRef,
        this.formRef
      );
    },
    // 当点击format格式菜单后，赋值给format,并关闭当前格式的popover
    handleFormatClick(item) {
      this.form.format = item.value;
      this.$forceUpdate();
      this.$nextTick(() => {
        this.$refs["formatRef"].doClose();
      });
      this.$emit("updateSchemaContent", this.isArrayItems, "format", item.value);
    },
    // 输入的数据类型为number的变量发生变化时
    handleChange(val, sign) {
      this.form[sign] = val == null || val == "" ? null : Number(val);
      this.$emit("updateSchemaContent", this.isArrayItems, sign, Number(val));
      setTimeout(() => {
        // 当数值改变时，如果对应的选择框处于选中状态则同步更新选择框对应的值
        if (sign == "minimum" && this.form.exclusiveMinimum) {
          this.form.exclusiveMinimum = Number(val)
          this.handleCheckBoxChange(Number(val), "exclusiveMinimum")
        }
        if (sign == "maximum" && this.form.exclusiveMaximum) {
          this.form.exclusiveMaximum = Number(val)
          this.handleCheckBoxChange(Number(val), "exclusiveMaximum")
        }
      }, 0)

    },
    // 排除最大最小值的选择框发生变化时
    handleCheckBoxChange(value, sign) {
      if (value) {
        this.$emit("updateSchemaContent", sign, value);
      } else {
        this.$emit("updateSchemaContent", sign, null);
      }
    }
  },
};
</script>

<style lang="scss" scoped>
.data-type-form-container {
  width: 100%;
}

.menu-item {
  position: relative;
  height: 30px;

  .menu-item-text {
    height: 30px;
    line-height: 30px;
    color: var(--ui-text-color);
    font-size: 14px;
    box-sizing: border-box;
    cursor: pointer;
  }
}

.menu-item:hover {
  cursor: pointer;
  background-color: var(--ui-item-hover-bg);
  border-radius: 6px;
}
</style>
<style scoped>
.data-type-form-container>>>.el-form-item {
  margin-bottom: 6px;
  text-align: left;
}

.data-type-form-container>>>.el-form-item__label {
  font-size: 12px;
  line-height: 25px;
  font-weight: normal;
}

.data-type-form-container>>>.el-form--label-top .el-form-item__label {
  padding: 0;
}

.string-text>>>.el-input__inner {
  color: #139659;
}

.integer-text>>>.el-input__inner,
.number-text>>>.el-input__inner {
  color: #ee46bc;
}

.boolean-text>>>.el-input__inner {
  color: #f37acf;
}

.array-text>>>.el-input__inner {
  color: #17b26a;
}

.object-text>>>.el-input__inner {
  color: #2e90fa;
}

.null-text>>>.el-input__inner,
.dictionary-text>>>.el-input__inner {
  color: #ef6820;
}

.any-text>>>.el-input__inner {
  color: #69affb;
}

.quote-text>>>.el-input__inner {
  color: #409eff;
}
</style>